<!--
 * @Author: pmy
 * @Date: 2021-07-26 10:32:01
 * @LastEditTime: 2023-07-31 15:27:23
 * @LastEditors: pmy
 * @Description: 系统用户
 * @FilePath: \bdcar-net\src\components\views\systemManage\systemUser.vue
-->
<template>
  <div>
    <div class="tablePage" v-loading="tableLoading">
      <div class="search">
        <span class="search-text">账号</span>
        <el-input clearable v-model="query.userName" placeholder="请输入账号" class="search-input"></el-input>
        
        <span class="search-text">姓名</span>
        <el-input clearable v-model="query.personName" placeholder="请输入姓名" class="search-input"></el-input>
        
        <div class="add-btn" @click="handleClick(null, 'add')" v-if="isEditPermission">
          <div class="btn-img"></div>新增
        </div>
        <div class="search-btn" @click="getTableData">
          <div class="btn-img"></div>查询
        </div>
      </div>
      <div class="base-table">
        <el-table highlight-current-row :data="tableData" :header-cell-style="{ 'text-align': 'left' }" height="100%">
          <el-table-column v-for="v in tableItems" :key="v.prop" :prop="v.prop" :label="v.name" align="left"
            header-align="left">
            <template slot-scope="scope">
              <span v-if="v.prop == 'roleType'"> {{ getRoleStr(scope.row[v.prop]) }}</span>
              <span v-else-if="scope.row[v.prop] !== ''"> {{ scope.row[v.prop] }}</span>
              <span v-else>---</span>
            </template>
          </el-table-column>

          <el-table-column label="操作" align="left">
            <template slot-scope="scope" v-if="isEditPermission">
              <div @click="handleClick(scope.row, 'Reset')" class="other-btn">重置密码</div>
              <div @click="handleClick(scope.row, 'edit')" class="edit-btn">
                <div class="btn-img"></div>编辑
              </div>
              <div @click="handleClick(scope.row, 'Delete')" class="delete-btn">
                <div class="btn-img"></div>删除
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="pagination">
        <el-pagination :page-size="pagination.pageSize" @size-change="handleSizeChange"
          @current-change="handleCurrentChange" :current-page="pagination.currentPage" :total="pagination.total"
          :page-sizes="[15, 50, 100, 300]" background layout="total,sizes, prev, pager, next, jumper"></el-pagination>
      </div>
      <el-dialog v-dialogDrag :visible="!!showWhich" top="8%" width="85rem" :close-on-click-modal="false"
        :before-close="handleCloseEdit">
        <template #title>
          <div class="dialog-title">
            <div class="cicle"></div>
            <span>{{ showWhichType === 1 ? '新增' : '编辑' }}</span>
          </div>
        </template>
        <div class="body scrollBody" style="overflow:auto" v-if="!!showWhich">
          <el-form :inline='true' :rules="SystemUserRules" ref="systemUserRef" :model="systemUserInfo">
            <el-form-item label="姓名" prop="personName">
              <el-input v-model.trim="systemUserInfo.personName"></el-input>
            </el-form-item>
            <el-form-item label="菜单权限" class="tree-dom">
              <el-tree :data="menu_options" :show-checkbox="systemUserInfo.roleType != '-1'" node-key="id"
                :props="menuProps" :default-expanded-keys="defaultOpenedMenu" check-strictly="true" :default-checked-keys="defaultCheckedMenu"
                ref="menuTree">
              </el-tree>
            </el-form-item>

            <el-form-item label="角色" prop="roleType">
              <el-select v-model="systemUserInfo.roleType" filterable :reserve-keyword="true"
                @visible-change="changeValueCategory($event)" ref="multipleselect">
                <el-option v-for="item in role_options" :key="item.value" :label="item.label" :value="item.value"
                  :disabled="item.value === ''"></el-option>
              </el-select>
            </el-form-item>

            <el-form-item label="账号" prop="userName">
              <el-input v-model.trim="systemUserInfo.userName"></el-input>
            </el-form-item>
            <el-form-item label="密码" prop="passwordTest" v-if="showWhichType">
              <el-input v-model.trim="systemUserInfo.passwordTest" type="password"></el-input>
            </el-form-item>
            <el-form-item label="再次输入密码" prop="password" v-if="showWhichType">
              <el-input v-model.trim="systemUserInfo.password" type="password"></el-input>
            </el-form-item>
          </el-form>
        </div>
        <div class="tool-bar">
          <div class="cancel-btn" @click="handleCloseEdit">关闭</div>
          <div class="submit-btn" @click="handleSystemUser">确定</div>
        </div>
      </el-dialog>
    </div>
  </div>
</template>
<script>
// -1：管理员   0：普通用户
import Vue from 'vue';
import { service } from "@/services/backServices"
import dayjs from 'dayjs'
import { TreeCreate } from "@/assets/js/createTree"
export default {
  name: "systemUser",
  data() {
    let pwdValidate = (rule, value, callback) => {
      if (this.showWhichType === 0) {
        callback()
      }
      if (value === '') {
        callback(new Error('请输入密码'));
      } else if (value !== this.systemUserInfo.passwordTest) {
        callback(new Error('两次密码输入不一致'))
      } else {
        callback()
      }
    }
    let passwordValidate = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请输入新密码"));
      } else {
        if (value.length < 8) {
          callback(new Error("密码要求长度8位以上"));
        }
        let MyRegExp =
          /^(?![A-z0-9]+$)(?=.[^%&',;=?$\x22])(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{8,100}$/
        if (!MyRegExp.test(value)) {
          callback(
            new Error("密码要包含大小写字母、数字和特殊符号")
          );
        } else {
          //校验通过
          callback();
        }
      }
    };
    return {
      tableLoading: false,
      //表格参数
      pagination: {
        total: 0,
        currentPage: 1,
        pageSize: 15,
      },
      //搜索使用参数
      query: {
        personName: '',
        userName: '',
      },
      userInfo: {},
      //表格数据
      tableItems: [
        { name: '账号', prop: "userName" },
        { name: '姓名', prop: "personName" },
        { name: '用户类型', prop: "roleType" },
      ],
      tableData: [],

      //用户类型
      role_options: [
        { label: "普通用户", value: "0" },
        { label: "管理员", value: "-1" },
      ],
      // menu参数
      menu_options: [],
      menuProps: {
        label: 'name',
        children: 'children',
        disabled: 'disabled'
      },
      defaultOpenedMenu: ['-1'],
      defaultCheckedMenu: [],
      // 显示遮罩层
      showWhich: false,
      // 1则添加 为0则编辑
      showWhichType: '',
      // 记录初始化的数据，在编辑后充值
      initSystemUserInfo: {},
      row: {},
      systemUserInfo: {
        // 账号
        userName: '',
        // 密码
        password: '',
        // 用户姓名
        personName: '',
        // 菜单JSON
        views: null,
        // 角色类型   -1：管理员   0：普通用户
        roleType: '0',
        // 重复校验
        passwordTest: '',
      },
      SystemUserRules: {
        // 账号
        userName: [
          { required: true, message: '请输入账号', trigger: 'change' },
        ],
        // 姓名
        personName: [
          { required: true, message: '请输入用户姓名', trigger: 'blur' },
          { required: true, message: '请输入用户姓名', trigger: 'change' },
        ],
        passwordTest: [
          { required: true, validator: passwordValidate, trigger: 'blur' },
          { required: true, message: '请输入密码', trigger: 'change' },
        ],
        password: [
          { required: true, validator: pwdValidate, trigger: 'blur' },
          { required: true, message: '请输入新密码', trigger: 'change' },
        ]
      },
      tableAllData: [],
    };
  },
  mounted() {
    //初始化表格数据
    this.getTableData();
    this.initMenuTree();
    this.initSystemUserInfo = JSON.parse(JSON.stringify(this.systemUserInfo));
  },
  methods: {
    setTableData() {
      this.tableData = this.tableAllData.slice(
        (this.pagination.currentPage - 1) * this.pagination.pageSize,
        this.pagination.currentPage * this.pagination.pageSize
      )
    },
    
    object2FormData(obj) {
      const formData = new FormData();
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          formData.append(key, obj[key]);
        }
      }
      return formData;
    },

    initMenuTree() {
      service({
        url: "getAllView",
        method: "post"
      }).then((res) => {
        if (res.data.code == 200) {
          res.data.data.sort((a, b) => a.orderKey - b.orderKey)
          let tree = new TreeCreate(res.data.data)
          this.menu_options = [tree.getData()]
        }
      }).catch((err) => {
        this.menu_options = []
      });
    },

    // 获取用户类型
    getRoleStr(val) {
      for (let i = 0; i < this.role_options.length; i++) {
        if (val === this.role_options[i].value) return this.role_options[i].label
      }
    },

    changeValueCategory($event) {
      // categoryBox 在export default 外设置的 var categoryBox = null
      // 获取显示范围的元素
      let categoryBox = document.getElementsByClassName('scrollBody')[0]

      //做判断：如果下拉框打开
      if ($event === true) {
        // 监听滚动条
        categoryBox.onscroll = () => {
          this.$refs.multipleselect.blur()
        }
      }
    },
    open() {
      this.$refs.multipleselect.blur()
    },
    //表格参数改变触发
    handleSizeChange: function (val) {
      this.pagination.pageSize = val;
      this.setTableData();
    },
    handleCurrentChange: function (currentPage) {
      this.pagination.currentPage = currentPage;
      this.setTableData();
    },
    resetSystemUserInfo() {
      this.systemUserInfo = JSON.parse(JSON.stringify(this.initSystemUserInfo));
    },
    setSystemUserInfo(row) {
      this.systemUserInfo = JSON.parse(JSON.stringify(row));
    },
    // 增删改查
    handleClick(row, obj) {
      switch (obj) {
        case "add":
          this.showWhichType = 1;
          this.showWhich = true;
          this.systemUserInfo = JSON.parse(JSON.stringify(this.initSystemUserInfo));
          this.$nextTick(() => {
            this.$refs['systemUserRef'].resetFields();
          })
          break;
        case "edit":
          this.row = row;
          this.setSystemUserInfo(row);
          this.systemUserInfo.passwordTest = 'DO NOT NEED VALIDATE';
          this.showWhichType = 0;
          this.showWhich = true;
          this.$nextTick(() => {
            this.$refs.menuTree.setCheckedKeys(JSON.parse(row.views));
          })
          break;
        case "Delete":
          this.deleteSystemUser(row);
          break;
        case "Reset":
          this.resetPassword(row);
          break;
        default:
          break;
      }
    },
    // 关闭
    handleCloseEdit() {
      if (this.showWhichType === 0) {
        this.resetSystemUserInfo()
        this.row = {}
      }
      this.showWhich = false;
    },
    //获取表格数据
    getTableData() {
      this.tableLoading = true
      service({
        url: "searchUsers",
        method: "post",
        data: this.object2FormData(this.query)
      }).then((res) => {
        this.tableLoading = false
        if (res.data.code == 200) {
          this.tableAllData = res.data.data;
          this.setTableData();
          this.pagination.total = res.data.data.length;
          this.pagination.total = res.data.data.length
          if (this.tableData.length == 0 && this.pagination.currentPage != 1) {
            this.pagination.currentPage = 1;
            this.getTableData();
          }
        }
      }).catch((err) => {
        this.tableLoading = false
        this.tableData = []
      });
    },
    handleSystemUser() {
      this.$refs.systemUserRef.validate((valid) => {
        if (valid) {
          switch (this.showWhichType) {
            case 1:
              this.addSystemUser();
              break;
            case 0:
              this.updateSystemUser();
              break;
            default:
              break;
          }
        }
      })
    },
    async addSystemUser() {
      let { passwordTest, ...model } = this.systemUserInfo
      model.views = JSON.stringify(this.$refs.menuTree.getCheckedKeys())
      const addData = await service({
        url: "register",
        method: "post",
        data: this.object2FormData(model)
      })
      if (addData.data.code == 200) {
        this.$notify({
          message: "添加用户成功！",
          type: "success",
          position: "bottom-right",
          duration: 2000,
        });
      }
      this.getTableData();
      this.showWhich = false;
    },
    async updateSystemUser() {
      const { password, passwordTest, ...model } = this.systemUserInfo;
      model.views = JSON.stringify(this.$refs.menuTree.getCheckedKeys())
      const updateData = await service({
        url: "editUser",
        method: "post",
        data: this.object2FormData(model)
      })
      if (updateData.data.code == 200) {
        this.$notify({
          message: "修改用户成功！",
          type: "success",
          position: "bottom-right",
          duration: 2000,
        });
        this.row = {};
        this.getTableData();
        this.showWhich = false;
        this.resetSystemUserInfo();
      }
    },
    deleteSystemUser(row) {
      this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        let params = new FormData()
        params.append("id", row.id)
        const { data } = await service({
          url: "unregister",
          method: "post",
          data: params
        })
        if (data.code == 200) {
          this.getTableData();
          this.$message({
            type: 'success',
            message: '删除成功!'
          });
          return
        }
      })
    },
    resetPassword(info) {
      let password = "Sibao@123";
      this.$confirm('此操作将重置该用户密码(重置密码：' + password + '), 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const data = new FormData()
        data.append("id", info.id)
        data.append("password", password)
        service({
          url: "editUser",
          method: "post",
          data: data
        }).then(res => {
          if (res.data.code == 200) {
            this.$notify({
              message: "重置密码成功！",
              type: "success",
              position: "bottom-right",
              duration: 2000,
            });
          }
        });
      })
    }
  },
  computed: {
    //获取用户信息
    userData() {
      return this.$store.state.currentUser;
    },
    isEditPermission() {
      return this.userData.roleType == '-1'
    }
  },
}
</script>
<style scoped lang="less">
.tree-dom {
  float: right;

  ::v-deep .el-form-item__content {
    width: 240px;
    height: 300px;
    margin-top: 10px;
    overflow-y: auto;
  }
}

::v-deep {
  .search-input {
    width: 220px;
  }

  .el-tree-node__label {
    line-height: 26px;
  }
}
</style>